package com.edu.hre.struts.action.admin;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.edu.hre.common.utils.BeanFinder;
import com.edu.hre.common.utils.ComboBoxInit;
import com.edu.hre.common.utils.CommonUtils;
import com.edu.hre.common.utils.RequestUtils;
import com.edu.hre.db.pojo.HreUserRoleScreen;
import com.edu.hre.db.service.BaseService;
import com.edu.hre.struts.form.admin.PaymentForm;
import com.edu.hre.struts.form.admin.PayrollForm;
import com.ibm.icu.util.Calendar;

public class PayrollAction extends DispatchAction {

	private static final Logger logger = Logger.getLogger(PayrollAction.class);
	private static final BaseService baseService = BeanFinder.getBean(BaseService.BEAN_NAME, BaseService.class);
	private final String ACTION_NAME = "payroll";
 
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

		// Print source code location.
		CommonUtils.println(CommonUtils.getSourceCodeLocation());
		
		// Get the authorization of the current user for the specified operations. 
		HreUserRoleScreen userRoleScreen = (HreUserRoleScreen) request.getSession().getAttribute(RequestUtils.Attribute.HreUserRoleScreen);
		
		PayrollForm beanForm = (PayrollForm) form;
		
		if (beanForm.getMonth() == 0) {
			Calendar cal = Calendar.getInstance();
			beanForm.setMonth(cal.get(Calendar.MONTH));
			beanForm.setYear(cal.get(Calendar.YEAR));
			
			if (beanForm.getMonth() == 0) {
				beanForm.setMonth(12);
				beanForm.setYear(beanForm.getYear() - 1);
			}
		}

		// Set authorization information for the form in order to determine if the ADD or DELETE button is shown.
		beanForm.setCanAdd(false);
		beanForm.setCanDelete(false); 
		
		// Get the sortBy parameter to determine how the result list is sorted! Then get the list and return.
		String sortBy = RequestUtils.getParameterStr(request, "sort", null);
		if (sortBy != null) { 
			beanForm.setAsc(!beanForm.isAsc());
			CommonUtils.sortCollection(beanForm.getAllPayments(), beanForm.isAsc(), sortBy);
			return mapping.findForward(ACTION_NAME);
		}
		
		initFormBean(beanForm);

		List<PaymentForm> allPayments = new ArrayList<PaymentForm>();
		
		double totalCom = 0;
		double totalSal = 0;
		double totalAmo = 0;
		
		String sql = 
				" SELECT Table0.emp_number AS col1, " + "\n" +
				" CONCAT(Table0.emp_lastname, ' ', Table0.emp_middle_name, ' ', Table0.emp_firstname) AS col2, " + "\n" +
				" Table2.empAmount AS col3, " + "\n" +
				" Table3.Salary AS col4 " + "\n" +
				" FROM " + "\n" +
				" hre_employee AS Table0 " + "\n" +
				" LEFT OUTER JOIN " + "\n" +
				" ( " + "\n" +
				"     SELECT emp.emp_number, (com.amount * empCom.kpi / Table1.TotalKpi) AS empAmount " + "\n" +
				"     FROM hre_employee AS emp, hre_compensation AS com, hre_emp_compensation AS empCom, " + "\n" +
				"     ( " + "\n" +
				"         SELECT SUM(empCom.kpi) AS TotalKpi, empCom.year, empCom.month " + "\n" +
				"         FROM hrentry_db.hre_emp_compensation AS empCom " + "\n" +
				"         WHERE " + "\n" +
				"         empCom.year = " + beanForm.getYear() + " " + "\n" +
				"         AND empCom.month = " + beanForm.getMonth() + " " + "\n" +
				"         GROUP BY empCom.year, empCom.month " + "\n" +
				"     ) AS Table1 " + "\n" +
				"     WHERE " + "\n" +
				"     empCom.year = Table1.year " + "\n" +
				"     AND empCom.month = Table1.month " + "\n" +
				"     AND emp.emp_number = empCom.emp_number " + "\n" +
				"     AND com.year = Table1.year " + "\n" +
				"     AND com.month = Table1.month " + "\n" +
				"     AND emp.is_deleted = 0 " + "\n" +
				" ) AS Table2 ON Table0.emp_number = Table2.emp_number " + "\n" +
				" LEFT OUTER JOIN " + "\n" +
				" ( " + "\n" +
				"     SELECT empSal.emp_number, SUM(empSal.ebsal_basic_salary) AS Salary " + "\n" +
				"     FROM hrentry_db.hre_emp_basicsalary AS empSal " + "\n" +
				"     GROUP BY empSal.emp_number " + "\n" +
				" ) AS Table3 " + "\n" +
				" ON Table0.emp_number = Table3.emp_number " + "\n" +
				" WHERE Table0.is_deleted = 0 " + "\n";
		
		ArrayList<Object> params = new ArrayList<Object>();
		if (beanForm.getEmployeeName() != null && !"".equals(beanForm.getEmployeeName())) {
				sql += " AND CONCAT(Table0.emp_lastname, ' ', Table0.emp_middle_name, ' ', Table0.emp_firstname, ' [', Table0.main_username, ']') = ? ";
				params.add(beanForm.getEmployeeName());
		}
		
		sql += " ORDER BY Table0.emp_number";

		List <Object[]> listObject = baseService.listArrayObject(sql, -1, 0, params.toArray());
		for(int i = 0; listObject != null && i < listObject.size(); i++){
			
			try {

				Object[] objs = listObject.get(i);
				PaymentForm payment = new PaymentForm();

				payment.setEmpNumber(CommonUtils.parseInt(CommonUtils.normalizeObjectToString(objs[1], "0"), 0));
				payment.setEmployeeName(CommonUtils.normalizeObjectToString(objs[2], ""));
				
				double compen = 0;
				try {
					compen = Double.parseDouble(CommonUtils.normalizeObjectToString(objs[3], "0"));
				} catch (Exception e) {
					compen = 0;
				}
				payment.setCompensations(String.format("%,15.2f", compen) + " VND");
				totalCom += compen;
				
				double sal = 0;
				try {
					sal = Double.parseDouble(CommonUtils.normalizeObjectToString(objs[4], "0"));
				} catch (Exception e) {
					compen = 0;
				}
				payment.setSalary(String.format("%,15.2f", sal) + " VND");
				totalSal += sal;
				
				payment.setAmount(String.format("%,15.2f", sal + compen) + " VND");
				totalAmo += sal + compen;

				allPayments.add(payment);
			} catch (Exception e) {
				CommonUtils.println(e.getMessage());
			}
		}
		
		beanForm.setAllPayments(allPayments);
		beanForm.setTotalItems(allPayments.size());
		beanForm.setTotalPage(1);
		
		PaymentForm totalPay = new PaymentForm();
		totalPay.setEmployeeName("Total");
		totalPay.setCompensations(String.format("%,15.2f", totalCom) + " VND");
		totalPay.setSalary(String.format("%,15.2f", totalSal) + " VND");
		totalPay.setAmount(String.format("%,15.2f", totalAmo) + " VND");
		allPayments.add(totalPay);

		return mapping.findForward(ACTION_NAME);
	}
	
	private void initFormBean(PayrollForm beanForm) {

		beanForm.setAllMonths(ComboBoxInit.getAllMonths(false));
	}
}
